home *** CD-ROM | disk | FTP | other *** search
Visual Basic class definition | 2001-10-08 | 17.4 KB | 573 lines |
- VERSION 1.0 CLASS
- BEGIN
- MultiUse = -1 'True
- Persistable = 0 'NotPersistable
- DataBindingBehavior = 0 'vbNone
- DataSourceBehavior = 0 'vbNone
- MTSTransactionMode = 0 'NotAnMTSObject
- END
- Attribute VB_Name = "CD3DAnimation"
- Attribute VB_GlobalNameSpace = False
- Attribute VB_Creatable = True
- Attribute VB_PredeclaredId = False
- Attribute VB_Exposed = False
-
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '
- ' Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
- '
- ' File: D3DAnimation.cls
- ' Content: D3D Visual Basic Framework Animation Class
- '
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
-
- Option Explicit
-
- Public ObjectName As String
-
- Private Type KEYHEADER
- keytype As Long
- keycount As Long
- End Type
-
- Private Type RMROTATEKEY
- time As Long
- nFloats As Long
- w As Single
- x As Single
- y As Single
- z As Single
- End Type
-
- Private Type D3DMATRIXKEY
- time As Long
- nFloats As Long
- matrix As D3DMATRIX
- End Type
-
-
- Const kAnimGrowSize = 10
-
- Dim m_RotateKeys() As D3DROTATEKEY
- Dim m_ScaleKeys() As D3DVECTORKEY
- Dim m_PositionKeys() As D3DVECTORKEY
- Dim m_RMRotateKeys() As RMROTATEKEY
- Dim m_MatrixKeys() As D3DMATRIXKEY
-
- Dim m_NumRotateKeys As Long
- Dim m_NumScaleKeys As Long
- Dim m_NumPositionKeys As Long
- Dim m_NumMatrixKeys As Long
- Dim m_strFrameName As String
- Dim m_frame As CD3DFrame
- Dim m_iMatrixKey As Long
-
-
- Dim m_Children() As CD3DAnimation
- Dim m_NumChildren As Long
- Dim m_MaxChildren As Long
-
- '-----------------------------------------------------------------------------
- ' Name: ParseAnimSet
- ' Desc: called from D3DUtil_LoadFromFile
- '-----------------------------------------------------------------------------
- Friend Sub ParseAnimSet(FileData As DirectXFileData, parentFrame As CD3DFrame)
- On Local Error Resume Next
- ObjectName = FileData.GetName()
-
- Dim ChildData As DirectXFileData
- Dim NewAnim As CD3DAnimation
- Dim ChildObj As DirectXFileObject
- Dim ChildRef As DirectXFileReference
-
- Set ChildObj = FileData.GetNextObject()
-
- Do While Not ChildObj Is Nothing
-
- Set ChildData = ChildObj
- If Err.Number = 0 Then
-
- If ChildData.GetType = "TID_D3DRMAnimation" Then
- Set NewAnim = New CD3DAnimation
- AddChild NewAnim
- NewAnim.ParseAnim ChildData, Me, parentFrame
- End If
- End If
-
- Err.Clear
- Set ChildRef = ChildObj
-
- If Err.Number = 0 Then
- Set ChildData = ChildRef.Resolve
-
- Set NewAnim = New CD3DAnimation
- AddChild NewAnim
- NewAnim.ParseAnim ChildData, Me, parentFrame
- End If
-
- Err.Clear
-
- Set ChildObj = FileData.GetNextObject()
- Loop
-
- End Sub
-
- '-----------------------------------------------------------------------------
- ' Name: GetChild
- ' Desc: return child Animation
- '-----------------------------------------------------------------------------
-
- Public Function GetChild(i As Long) As CD3DAnimation
- Set GetChild = m_Children(i)
- End Function
-
- '-----------------------------------------------------------------------------
- ' Name: GetChildCount
- ' Desc: return number of child animations
- '-----------------------------------------------------------------------------
-
- Public Function GetChildCount() As Long
- GetChildCount = m_NumChildren
- End Function
-
-
- '-----------------------------------------------------------------------------
- ' Name: AddChild
- ' Desc: Add child animation
- '-----------------------------------------------------------------------------
-
- Public Sub AddChild(child As CD3DAnimation)
- If child Is Nothing Then Exit Sub
-
- If m_MaxChildren = 0 Then
- m_MaxChildren = kAnimGrowSize
- ReDim m_Children(m_MaxChildren)
- ElseIf m_NumChildren >= m_MaxChildren Then
- m_MaxChildren = m_MaxChildren + kAnimGrowSize
- ReDim Preserve m_Children(m_MaxChildren)
- End If
-
- Set m_Children(m_NumChildren) = child
- m_NumChildren = m_NumChildren + 1
- End Sub
-
-
- '-----------------------------------------------------------------------------
- ' Name: SetFrame
- ' Desc: set Frame to be animated
- '-----------------------------------------------------------------------------
- Public Sub SetFrame(frame As CD3DFrame)
- Set m_frame = frame
- m_strFrameName = frame.ObjectName
- End Sub
-
- '-----------------------------------------------------------------------------
- ' Name: GetFrame
- ' Desc: return frame being animated
- '-----------------------------------------------------------------------------
- Public Function GetFrame() As CD3DFrame
- Set GetFrame = m_frame
- End Function
-
-
- '-----------------------------------------------------------------------------
- ' Name: ParseAnim
- ' Desc: Called by ParseAnimSet
- '-----------------------------------------------------------------------------
-
- Friend Sub ParseAnim(FileData As DirectXFileData, parentAnimation As CD3DAnimation, parentFrame As CD3DFrame)
- On Local Error Resume Next
- ObjectName = FileData.GetName()
-
- Dim dataSize As Long
- Dim KeyHead As KEYHEADER
- Dim size As Long
- Dim newFrame As CD3DFrame
- Dim ChildObj As DirectXFileObject
- Dim ChildData As DirectXFileData
- Dim ChildReference As DirectXFileReference
- Dim strChunkType As String
- Dim i As Long
-
- Set ChildObj = FileData.GetNextObject()
-
- Do While Not ChildObj Is Nothing
-
- Set ChildReference = ChildObj
- If Err.Number = 0 Then
-
- Set ChildData = ChildReference.Resolve()
-
-
- If ChildData.GetType = "TID_D3DRMFrame" Then
- m_strFrameName = ChildData.GetName()
- Set m_frame = parentFrame.FindChildObject(m_strFrameName, 0)
- End If
-
- Set ChildReference = Nothing
- End If
- Err.Clear
-
- Set ChildData = ChildObj
- If Err.Number = 0 Then
-
- strChunkType = ChildData.GetType
- Select Case strChunkType
- Case "TID_D3DRMFrame"
- Set newFrame = New CD3DFrame
- newFrame.InitFromXOF g_dev, ChildData, parentFrame
- Set newFrame = Nothing
-
- Case "TID_D3DRMAnimationOptions"
-
- Case "TID_D3DRMAnimationKey"
- dataSize = ChildData.GetDataSize("")
- ChildData.GetDataFromOffset "", 0, 8, KeyHead
-
- Select Case KeyHead.keytype
- Case 0 'ROTATEKEY
- ReDim m_RMRotateKeys(KeyHead.keycount)
- ReDim m_RotateKeys(KeyHead.keycount)
- size = Len(m_RMRotateKeys(0)) * KeyHead.keycount
- ChildData.GetDataFromOffset "", 8, size, m_RMRotateKeys(0)
- m_NumRotateKeys = KeyHead.keycount
-
- 'NOTE x files are w x y z and QUATERNIONS are x y z w
- 'so we loop through on load and copy the values
- For i = 0 To m_NumRotateKeys - 1
- With m_RotateKeys(i)
- .time = m_RMRotateKeys(i).time
- If g_InvertRotateKey Then
- .quat.w = -m_RMRotateKeys(i).w
- Else
- .quat.w = m_RMRotateKeys(i).w
- End If
- .quat.x = m_RMRotateKeys(i).x
- .quat.y = m_RMRotateKeys(i).y
- .quat.z = m_RMRotateKeys(i).z
- End With
- Next
- ReDim m_RMRotateKeys(0)
-
- Case 1 'SCALE KEY
- ReDim m_ScaleKeys(KeyHead.keycount)
- size = Len(m_ScaleKeys(0)) * KeyHead.keycount
- ChildData.GetDataFromOffset "", 8, size, m_ScaleKeys(0)
- m_NumScaleKeys = KeyHead.keycount
-
- Case 2 'POSITION KEY
- ReDim m_PositionKeys(KeyHead.keycount)
- size = Len(m_PositionKeys(0)) * KeyHead.keycount
- ChildData.GetDataFromOffset "", 8, size, m_PositionKeys(0)
- m_NumPositionKeys = KeyHead.keycount
-
- Case 4 'MATRIX KEY
- ReDim m_MatrixKeys(KeyHead.keycount)
- size = Len(m_MatrixKeys(0)) * KeyHead.keycount
- ChildData.GetDataFromOffset "", 8, size, m_MatrixKeys(0)
- m_NumMatrixKeys = KeyHead.keycount
-
- End Select
-
-
- End Select
- End If
-
- Set ChildData = Nothing
- Set ChildReference = Nothing
-
- Set ChildObj = FileData.GetNextObject()
- Loop
-
-
-
- End Sub
-
-
-
- '-----------------------------------------------------------------------------
- ' Name: ComputeP1234
- ' Desc: Aux function to compute 4 nearest keys
- '-----------------------------------------------------------------------------
- Private Sub ComputeP1234(j As Long, maxNum As Long, ByRef p1 As Long, ByRef p2 As Long, ByRef p3 As Long, ByRef p4 As Long)
-
- p1 = j: p2 = j: p3 = j: p4 = j
-
- If j > 0 Then
- p1 = j - 2: p2 = j - 1
- End If
- If j = 1 Then
- p1 = j - 1: p2 = j - 1
- End If
- If j < (maxNum) - 1 Then p4 = j + 1
- End Sub
-
-
- '-----------------------------------------------------------------------------
- ' Name: SetTime
- ' Desc: Sets the matrix of the frame being animated
- '-----------------------------------------------------------------------------
- Public Sub SetTime(t As Single)
- Dim t2 As Single
- Dim i As Long, j As Long
- Dim p1 As Long, p2 As Long, p3 As Long, p4 As Long
- Dim f1 As Single, f2 As Single, f3 As Single, f4 As Single
- Dim rM As D3DMATRIX, rQuat As D3DQUATERNION, rPos As D3DVECTOR, rScale As D3DVECTOR
-
- Dim a As D3DVECTOR, b As D3DVECTOR
- Dim q1 As D3DQUATERNION, q2 As D3DQUATERNION
- Dim s As Single
-
- Dim child As CD3DAnimation
- Dim LastT As Single
-
- 'Check children
- For i = 1 To m_NumChildren
- Set child = m_Children(i - 1)
- If Not child Is Nothing Then
- child.SetTime t
- End If
- Set child = Nothing
- Next
-
- If m_frame Is Nothing Then Exit Sub
-
- 'set components to identity incase we dont have any keys.
- D3DXMatrixIdentity rM
- rScale = vec3(1, 1, 1)
-
- D3DXQuaternionIdentity rQuat
-
-
- t2 = t
-
- 'loop matrix keys
- If m_NumMatrixKeys > 0 Then
- t2 = t
- LastT = m_MatrixKeys(m_NumMatrixKeys - 1).time
- If t > LastT Then
- i = t \ LastT
- t2 = t - i * LastT
- Else
-
- End If
-
-
- 'optimizations
- Dim tAt As Single, tNext1 As Single, tNext2 As Single
-
- If m_iMatrixKey < m_NumMatrixKeys - 2 Then
- tAt = m_MatrixKeys(m_iMatrixKey).time
- tNext1 = m_MatrixKeys(m_iMatrixKey + 1).time
- tNext2 = m_MatrixKeys(m_iMatrixKey + 2).time
- If tAt < t2 And t2 <= tNext1 Then Exit Sub
-
- If tNext1 < t2 And t2 <= tNext2 Then
- m_iMatrixKey = m_iMatrixKey + 1
- If m_iMatrixKey > m_NumMatrixKeys Then m_iMatrixKey = 0
- m_frame.SetMatrix m_MatrixKeys(m_iMatrixKey).matrix
- End If
-
- End If
-
- 'linear search
- For i = 1 To m_NumMatrixKeys
- If m_MatrixKeys(i - 1).time > t2 Then
- m_frame.SetMatrix m_MatrixKeys(i - 1).matrix
- m_iMatrixKey = i - 1
-
- Exit Sub
- End If
- Next
-
- End If
-
- '.................
-
-
- 'loop position keys
- If m_NumPositionKeys > 0 Then
- t2 = t
- LastT = m_PositionKeys(m_NumPositionKeys - 1).time
- If t > LastT Then
- i = t \ LastT
- t2 = t - i * LastT
- End If
- End If
-
- 'Check Position Keys
- For i = 1 To m_NumPositionKeys
- j = i - 1
-
- If m_PositionKeys(j).time > t2 Then
-
- ComputeP1234 j, m_NumPositionKeys, p1, p2, p3, p4
- f1 = m_PositionKeys(p1).time
- f2 = m_PositionKeys(p2).time
- f3 = m_PositionKeys(p3).time
- f4 = m_PositionKeys(p4).time
-
-
- If ((f3 - f2) = 0) Then
- s = 1
- Else
- s = (t2 - f2) / (f3 - f2)
- End If
-
- a = m_PositionKeys(p2).vec
- b = m_PositionKeys(p3).vec
-
-
- D3DXVec3Lerp rPos, a, b, s
- Exit For
- End If
- Next
-
-
-
- 'loop scale keys
- If m_NumScaleKeys > 0 Then
- t2 = t
- LastT = m_ScaleKeys(m_NumScaleKeys - 1).time
- If t > LastT Then
- i = t \ LastT
- t2 = t - i * LastT
- End If
- End If
-
-
- 'Check Scale Keys
- For i = 1 To m_NumScaleKeys
- j = i - 1
- If m_ScaleKeys(j).time > t2 Then
-
- ComputeP1234 j, m_NumScaleKeys, p1, p2, p3, p4
- f1 = m_ScaleKeys(p1).time
- f2 = m_ScaleKeys(p2).time
- f3 = m_ScaleKeys(p3).time
- f4 = m_ScaleKeys(p4).time
-
- If ((f3 - f2) = 0) Then
- s = 1
- Else
- s = (t2 - f2) / (f3 - f2)
- End If
-
- a = m_ScaleKeys(p2).vec
- b = m_ScaleKeys(p3).vec
-
-
- D3DXVec3Lerp rScale, a, b, s
- Exit For
- End If
- Next
-
-
- 'loop rotate keys
- If m_NumRotateKeys > 0 Then
- t2 = t
- LastT = m_RotateKeys(m_NumRotateKeys - 1).time
- If t > LastT Then
- i = t \ LastT
- t2 = t - i * LastT
- End If
- End If
-
- 'Check Rotate Keys
- For i = 1 To m_NumRotateKeys
- j = i - 1
-
- If m_RotateKeys(j).time > t2 Then
-
-
-
- ComputeP1234 j, m_NumRotateKeys, p1, p2, p3, p4
- f1 = m_RotateKeys(p1).time
- f2 = m_RotateKeys(p2).time
- f3 = m_RotateKeys(p3).time
- f4 = m_RotateKeys(p4).time
-
- If ((f3 - f2) = 0) Then
- s = 1
- Else
- s = (t2 - f2) / (f3 - f2)
- End If
-
- q1 = m_RotateKeys(p2).quat
- q2 = m_RotateKeys(p3).quat
-
- D3DXQuaternionSlerp rQuat, q1, q2, s
- Exit For
- End If
- Next
-
- Dim temp1 As D3DMATRIX
- Dim temp2 As D3DMATRIX
- Dim temp3 As D3DMATRIX
-
- D3DXMatrixScaling temp1, rScale.x, rScale.y, rScale.z
- D3DXMatrixRotationQuaternion temp2, rQuat
- D3DXMatrixTranslation temp3, rPos.x, rPos.y, rPos.z
- D3DXMatrixMultiply rM, temp1, temp2
- D3DXMatrixMultiply rM, rM, temp3
-
- m_frame.SetMatrix rM
-
- End Sub
-
-
- '-----------------------------------------------------------------------------
- ' Name: AddRotateKey
- ' Desc:
- '-----------------------------------------------------------------------------
-
- Sub AddRotateKey(t As Long, quat As D3DQUATERNION)
-
- ReDim Preserve m_RotateKeys(m_NumRotateKeys)
-
- With m_RotateKeys(m_NumRotateKeys)
- .time = t
- .quat = quat
- End With
- m_NumRotateKeys = m_NumRotateKeys + 1
- End Sub
-
- '-----------------------------------------------------------------------------
- ' Name: AddScaleKey
- ' Desc:
- '-----------------------------------------------------------------------------
-
- Sub AddScaleKey(t As Long, scalevec As D3DVECTOR)
-
- ReDim Preserve m_ScaleKeys(m_NumScaleKeys)
-
-
-
- With m_ScaleKeys(m_NumScaleKeys)
- .time = t
- .vec = scalevec
- End With
-
- m_NumScaleKeys = m_NumScaleKeys + 1
- End Sub
-
- '-----------------------------------------------------------------------------
- ' Name: AddPositionKey
- ' Desc:
- '-----------------------------------------------------------------------------
- Sub AddPositionKey(t As Long, posvec As D3DVECTOR)
-
- ReDim Preserve m_PositionKeys(m_NumPositionKeys)
-
-
-
- With m_PositionKeys(m_NumPositionKeys)
- .time = t
- .vec = posvec
- End With
- m_NumPositionKeys = m_NumPositionKeys + 1
- End Sub
-
-
-
-